#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include "bmock_in_out_raw_mem.hpp"
#include "detail/bmock_raw_mem.hpp"
#include "detail/bmock_test_control_tools.hpp"
#include "bmock_util.hpp"

namespace bmock {

	static const size_t        L1         = 8;
	static const size_t        L2         = L1 + 1;
	static const int           in_buf[L1] = {0,1, 2, 3, 4, 5, 6, 7};
	static const int           out_buf[L2]= {8,9,10,11,12,13,14,15,16};
	static const unsigned char expected[] = {0x20,0x00,0x00,0x00//this length
		,0x24,0x00,0x00,0x00//next length
		,0x10,0x00,0x00,0x00//pad  length
		,0x15,0x00,0x00,0x00//T length
		,0x00,0x00,0x00,0x00
		,0x01,0x00,0x00,0x00
		,0x02,0x00,0x00,0x00
		,0x03,0x00,0x00,0x00
		,0x04,0x00,0x00,0x00
		,0x05,0x00,0x00,0x00
		,0x06,0x00,0x00,0x00
		,0x07,0x00,0x00,0x00
		,0x08,0x00,0x00,0x00
		,0x09,0x00,0x00,0x00
		,0x0A,0x00,0x00,0x00
		,0x0B,0x00,0x00,0x00
		,0x0C,0x00,0x00,0x00
		,0x0D,0x00,0x00,0x00
		,0x0E,0x00,0x00,0x00
		,0x0F,0x00,0x00,0x00
		,0x10,0x00,0x00,0x00};
	static const size_t        L3         = sizeof(expected);

	BOOST_AUTO_TEST_CASE(test_in_out_raw_mem) {
		BOOST_CHECK_NO_THROW(
			in_out_raw_mem_descr<int>  m1 = in_out_raw_mem(in_buf,L1,out_buf,L2);

		BOOST_CHECK_EQUAL(mismatch_at(expected,expected+L3,(const unsigned char *)m1.get_ptr()),L3);
		);	
	}

	BOOST_AUTO_TEST_CASE(test_get_in_out_rm_OK) {
		const in_out_raw_mem_descr<int>  m1 = in_out_raw_mem(in_buf,L1,out_buf,L2);
		const char name[] =              "raw_mem(out_buf,L1)";
		const control_tools_ptr          t(new test_control_tools());
		raw_mem_checker                  chk(t);

		chk.set_location(location(__FILE__,__LINE__+2));
		BOOST_CHECK_NO_THROW(
			const in_out_rm_pair m2(m1.get_ptr(),name,chk);
		BOOST_CHECK_EQUAL(L1*sizeof(int),m2.first.get_length());
		BOOST_CHECK_EQUAL(sizeof(in_buf),mismatch_at(m2.first.begin(),m2.first.end(),(const unsigned char *)in_buf));
		BOOST_CHECK_EQUAL(L2*sizeof(int),m2.second.get_length());
		BOOST_CHECK_EQUAL(sizeof(out_buf),mismatch_at(m2.second.begin(),m2.second.end(),(const unsigned char *)out_buf));
		);
	}

	static void test_memory(int *buf) {
		const control_tools_ptr t(new test_control_tools());
		raw_mem_checker         chk(t);
		const char name[] =     "raw_mem(out_buf,L1)";
		chk.set_location(location(__FILE__,__LINE__+1));
		const in_out_rm_pair    m1(buf,name,chk);

		BOOST_CHECK_EQUAL(sizeof(in_buf),mismatch_at(m1.first.begin(),m1.first.end(),(const unsigned char *)in_buf));
		BOOST_CHECK_EQUAL(sizeof(out_buf),mismatch_at(m1.second.begin(),m1.second.end(),(const unsigned char *)out_buf));
	}

	BOOST_AUTO_TEST_CASE(test_memory_management) {
		BOOST_CHECK_NO_THROW(test_memory(in_out_raw_mem(in_buf,L1,out_buf,L2)));
	}


	BOOST_AUTO_TEST_CASE(test_in_out_T_len_default_constructor) {
		in_out_T_len <int> f;
	}

	BOOST_AUTO_TEST_CASE(test_in_out_T_len_opertaor) {
		in_out_T_len <int> f((size_t) 8,(size_t) 8);
		in_out_T_len <int> g;
		BOOST_CHECK_NO_THROW(f=g);
		BOOST_CHECK_EQUAL(f.get_pad_length(),g.get_pad_length());
	}
}